package com.xiongwei.manageback.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.Quarter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.signers.JWTSignerUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiongwei.manageback.DTO.LoginDTO;
import com.xiongwei.manageback.config.TokenConfig;
import com.xiongwei.manageback.constant.Constant;
import com.xiongwei.manageback.domain.SysUser;
import com.xiongwei.manageback.exception.ServiceException;
import com.xiongwei.manageback.service.SysUserService;
import com.xiongwei.manageback.mapper.SysUserMapper;
import com.xiongwei.manageback.utils.AjaxResult;
import com.xiongwei.manageback.utils.JwtUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author a
 * @description 针对表【sys_user】的数据库操作Service实现
 * @createDate 2023-10-27 17:08:49
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
        implements SysUserService {

    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private TokenConfig tokenConfig;

    /**
     * 登录
     *
     * @param loginDTO
     * @return
     */
    @Override
    public AjaxResult login(LoginDTO loginDTO) {
//        校验验证码是否正确
        validResult(loginDTO);

//        查询用户是否存在
        SysUser user = userMapper.getByUsername(loginDTO.getUsername());
        if (ObjectUtil.isNull(user)) {
            throw new ServiceException(ServiceException.USER_NOT_FUND,"用户不存在");
        }
//        存在，查询密码是否正确
        if (!SecureUtil.md5(loginDTO.getPassword()).equals(user.getPassword())) {
            throw new ServiceException(ServiceException.PASS_WORD_ERROR,"密码错误");
        }
//        正确，封装用户信息进入token返回给前端
        BeanUtil.copyProperties(user,loginDTO);
        String token = JwtUtils.getToken(user.getId().toString(), user.getPassword());
        loginDTO.setToken(token);
        loginDTO.setUserId(user.getId());
        return AjaxResult.success(loginDTO);
    }

    /**
     * 校验验证码
     *
     * @return
     */
    @Nullable
    private void validResult(LoginDTO loginDTO) {
        String code = redisTemplate.opsForValue().get(Constant.CAPTCHA_CODE);
        if (StrUtil.isBlank(code) || !code.equals(loginDTO.getCode())) {
            throw new ServiceException(ServiceException.CAPTCHA_ERROR,"验证码已失效或错误");
        }
    }

    /**
     * 注册
     *
     * @param loginDTO
     */
    @Override
    public void register(LoginDTO loginDTO) {
//        校验验证码
        validResult(loginDTO);
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, loginDTO.getUsername());
        Long count = userMapper.selectCount(wrapper);
        if (count > 0){
            throw new ServiceException(ServiceException.USER_ALREADY_EXISTS,"用户名已存在");
        }
        SysUser user = BeanUtil.copyProperties(loginDTO, SysUser.class);
        user.setPassword(SecureUtil.md5(user.getPassword()));
        int insertResult = userMapper.insert(user);
        if (insertResult <= 0){
            throw new ServiceException(ServiceException.UN_KNOW_ERROR,"用户注册失败-未知错误-请联系你爸爸");
        }
    }

    @Override
    public List<Integer> userTendency() {
        int q1 = 0;
        int q2 = 0;
        int q3 = 0;
        int q4 = 0;
        List<SysUser> userList = list();
        for (SysUser user : userList) {
            Date createTime = user.getCreateTime();
            Quarter quarter = DateUtil.quarterEnum(createTime);
            switch (quarter){
                case Q1: q1 += 1;break;
                case Q2: q2 += 1;break;
                case Q3: q3 += 1;break;
                case Q4: q4 += 1;break;
                default: break;
            }
        }
//        redisTemplate.opsFor
        return CollUtil.newArrayList(q1,q2,q3,q4);
    }
}




